package com.mojang.mario.level;

import java.io.*;


public class Level
{
	public static final int NUM_LAYER = 3;
    public static final String[] BIT_DESCRIPTIONS = {//
    "BLOCK UPPER", //
            "BLOCK ALL", //
            "BLOCK LOWER", //
            "SPECIAL", //
            "BUMPABLE", //
            "BREAKABLE", //
            "PICKUPABLE", //
            "ANIMATED",//
    };

    public static byte[] TILE_BEHAVIORS = new byte[256];

    public static final int BIT_BLOCK_UPPER = 1 << 0;
    public static final int BIT_BLOCK_ALL = 1 << 1;
    public static final int BIT_BLOCK_LOWER = 1 << 2;
    public static final int BIT_SPECIAL = 1 << 3;
    public static final int BIT_BUMPABLE = 1 << 4;
    public static final int BIT_BREAKABLE = 1 << 5;
    public static final int BIT_PICKUPABLE = 1 << 6;
    public static final int BIT_ANIMATED = 1 << 7;

    private static final int FILE_HEADER = 0x271c4178;
    public static final int BLOCK_SIZE = 48;
    
    public int width;
    public int height;
    public int time;

    public byte[][][] layer;

    public SpriteTemplate[][] spriteTemplates;

    public int xExit;
    public int yExit;

    public Level(int width, int height)
    {
        this.width = width;
        this.height = height;
        this.time = 200;

        xExit = (width-3);
        yExit = 2;
        layer = new byte[NUM_LAYER][width][height];
        spriteTemplates = new SpriteTemplate[width][height];
    }

    public static Level load(DataInputStream dis) throws IOException
    {
        long header = dis.readLong();
        if (header != Level.FILE_HEADER) throw new IOException("File del livello non valido");
        int version = dis.read() & 0xff;
        int time = dis.readShort() & 0xffff;
        int width = dis.readShort() & 0xffff;
        int height = dis.readShort() & 0xffff;
        Level level = new Level(width, height);
        level.time = time;
        level.layer = new byte[NUM_LAYER][width][height];
        for (int i = 0; i < width; i++)
        {
        	for (int j = 0; j < NUM_LAYER; j++) {
        		dis.readFully(level.layer[j][i]);
			}
        }
        return level;
    }

    public void save(DataOutputStream dos) throws IOException
    {
        dos.writeLong(Level.FILE_HEADER);
        dos.write((byte) 0);

        dos.writeShort((short) time);
        
        dos.writeShort((short) width);
        dos.writeShort((short) height);

        for (int i = 0; i < width; i++)
        {
        	for (int j = 0; j < NUM_LAYER; j++) {
        		dos.write(layer[j][i]);
			};
        }
    }

    public void tick()
    {
        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
              //  if (layer1[x][y] > 0) layer1[x][y]--;
            }
        }
    }

    public byte getBlockCapped(int x, int y)
    {
        if (x < 0) x = 0;
        if (y < 0) y = 0;
        if (x >= width) x = width - 1;
        if (y >= height) y = height - 1;
        return layer[0][x][y];
    }

    public byte getByteLayer(int x, int y, int nLayer)
    {
        if (x < 0) x = 0;
        if (y < 0) return 0;
        if (x >= width) x = width - 1;
        if (y >= height) y = height - 1;
        return layer[nLayer][x][y];
    }

    public void setByteLayer(int x, int y, int nLayer, byte b)
    {
        if (x < 0) return;
        if (y < 0) return;
        if (x >= width) return;
        if (y >= height) return;
        layer[nLayer][x][y] = b;
    }
    
  
    public void setBlockData(int x, int y, byte b)
    {
        if (x < 0) return;
        if (y < 0) return;
        if (x >= width) return;
        if (y >= height) return;
        layer[1][x][y] = b;
    }

    public boolean isBlocking(int x, int y, float xa, float ya)
    {
        byte block = getByteLayer(x, y,1);
        System.out.print(" x: " + x);
        System.out.print(" y: " + y);
        System.out.print(" b: " + block);
        System.out.println();
        boolean blocking = (block > 0);
//        boolean blocking = ((TILE_BEHAVIORS[block & 0xff]) & BIT_BLOCK_ALL) > 0;
//        blocking |= (ya > 0) && ((TILE_BEHAVIORS[block & 0xff]) & BIT_BLOCK_UPPER) > 0;
//        blocking |= (ya < 0) && ((TILE_BEHAVIORS[block & 0xff]) & BIT_BLOCK_LOWER) > 0;

        return blocking;
    }

    public SpriteTemplate getSpriteTemplate(int x, int y)
    {
        if (x < 0) return null;
        if (y < 0) return null;
        if (x >= width) return null;
        if (y >= height) return null;
        return spriteTemplates[x][y];
    }

    public void setSpriteTemplate(int x, int y, SpriteTemplate spriteTemplate)
    {
        if (x < 0) return;
        if (y < 0) return;
        if (x >= width) return;
        if (y >= height) return;
        spriteTemplates[x][y] = spriteTemplate;
    }
}